package com.redrose.audioandvideo.camera2;

import android.app.Activity;
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;

import com.redrose.audioandvideo.camera.CameraUtil;
import com.redrose.audioandvideo.camera.DirectDrawer;
import com.redrose.audioandvideo.camera.H264Encoder;
import com.redrose.audioandvideo.utils.BitmapCallBack;
import com.redrose.audioandvideo.utils.LogUtils;
import com.redrose.audioandvideo.utils.ToastUtil;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

/**
 * Desc:
 *
 * @author: RedRose
 * Date: 2019/4/17
 * Email: yinsxi@163.com
 */

public class PreView2GlsurfaceView extends GLSurfaceView implements GLSurfaceView.Renderer,
        SurfaceTexture.OnFrameAvailableListener {
    public static final String TAG = "PreViewGlsurfaceView";
    private Context mContext;
    /**
     * 以OpenGL ES纹理的形式从图像流中捕获帧,我把叫做纹理层
     */
    SurfaceTexture mSurface;
    /**
     * 使用的纹理id
     */
    int mTextureID = -1;
    DirectDrawer mDirectDrawer;

    H264Encoder encoder; //自定义的编码操作类
    /**
     * 拍照 or 录像模式
     */
    public static final int TAKE_PHOTO_MODEL = 0;
    public static final int TAKE_VIDEO_MODEL = 1;
    private boolean isVideo = false;
    private Camera2Proxy camera2Proxy;
    private int mRatioWidth = 0;
    private int mRatioHeight = 0;
    private float mOldDistance;

    public PreView2GlsurfaceView(Context context) {
        this(context, null);
    }

    public PreView2GlsurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.mContext = context;
        setEGLContextClientVersion(2);
        setRenderer(this);
        //根据纹理层的监听，有数据就绘制 渲染模式
        //RENDERMODE_WHEN_DIRTY表示被动渲染，只有在调用requestRender或者onResume等方法时才会进行渲染。
        // RENDERMODE_CONTINUOUSLY表示持续渲染
        setRenderMode(RENDERMODE_WHEN_DIRTY);
        initCamera();

    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        LogUtils.d(TAG, "--onSurfaceCreated--");
        camera2Proxy.openCamera(getWidth(), getHeight());
        camera2Proxy.setPreviewSurface(mSurface);

        mDirectDrawer = new DirectDrawer(mTextureID);
    }

    private void initCamera() {
        camera2Proxy = new Camera2Proxy((Activity) getContext());
        //得到view表面的纹理id
        mTextureID = createTextureID();
        //使用这个纹理id得到纹理层SurfaceTexture
        mSurface = new SurfaceTexture(mTextureID);
        //监听纹理层
        mSurface.setOnFrameAvailableListener(this);



    }

    //    @Override
//    public void onSurfaceChanged(GL10 gl, int width, int height) {
//        LogUtils.d(TAG, "--onSurfaceChanged--");
//        GLES20.glViewport(0, 0, width, height);
//        // 渲染窗口大小发生改变或者屏幕方法发生变化时候回调
//        //如果还未预览，就开始预览
//
//
//    }
    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        Log.d(TAG, "onSurfaceChanged. thread: " + Thread.currentThread().getName());
        Log.d(TAG, "onSurfaceChanged. width: " + width + ", height: " + height);
        int previewWidth = camera2Proxy.getPreviewSize().getWidth();
        int previewHeight = camera2Proxy.getPreviewSize().getHeight();
        if (width > height) {
            setAspectRatio(previewWidth, previewHeight);
        } else {
            setAspectRatio(previewHeight, previewWidth);
        }
        GLES20.glViewport(0, 0, width, height);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        //系统在每次重画GLSurfaceView时调用这个方法
        //执行渲染工作
        GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
        //从图像流中将纹理图像更新为最近的帧
        mSurface.updateTexImage();
        mDirectDrawer.draw();
    }

    private void setAspectRatio(int width, int height) {
        if (width < 0 || height < 0) {
            throw new IllegalArgumentException("Size cannot be negative.");
        }
        mRatioWidth = width;
        mRatioHeight = height;
        post(new Runnable() {
            @Override
            public void run() {
                requestLayout(); // must run in UI thread
            }
        });
    }

    public Camera2Proxy getCameraProxy() {
        return camera2Proxy;
    }

    public SurfaceTexture getSurfaceTexture() {
        return mSurface;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        if (0 == mRatioWidth || 0 == mRatioHeight) {
            setMeasuredDimension(width, height);
        } else {
            if (width < height * mRatioWidth / mRatioHeight) {
                setMeasuredDimension(width, width * mRatioHeight / mRatioWidth);
            } else {
                setMeasuredDimension(height * mRatioWidth / mRatioHeight, height);
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getPointerCount() == 1) {
            // 点击聚焦
            camera2Proxy.focusOnPoint((int) event.getX(), (int) event.getY(), getWidth(), getHeight());
            return true;
        }
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_POINTER_DOWN:
                mOldDistance = getFingerSpacing(event);
                break;
            case MotionEvent.ACTION_MOVE:
                float newDistance = getFingerSpacing(event);
                if (newDistance > mOldDistance) {
                    camera2Proxy.handleZoom(true);
                } else if (newDistance < mOldDistance) {
                    camera2Proxy.handleZoom(false);
                }
                mOldDistance = newDistance;
                break;
            default:
                break;
        }
        return super.onTouchEvent(event);
    }

    private static float getFingerSpacing(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return (float) Math.sqrt(x * x + y * y);
    }

    @Override
    public void onFrameAvailable(SurfaceTexture surfaceTexture) {
        //回调接口，用于通知新的流帧可用
        //纹理层有新数据，就通知view绘制
        this.requestRender();
    }

    private int createTextureID() {
        int[] texture = new int[1];
        GLES20.glGenTextures(1, texture, 0);
        GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, texture[0]);
        GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
                GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
        GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
                GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
                GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
                GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
        return texture[0];
    }

    @Override
    public void onPause() {
        super.onPause();
        LogUtils.d(TAG, "--onPause--");
        //停止预览
//        camera2Proxy.stopPreview();
        camera2Proxy.releaseCamera();
    }
}
